﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CommunicationCore;
using CommunicationCore.OpcUaClient;
using Opc.Ua;
using Opc.Ua.Client;
using ScadaAPI.Models;
using SqlSugarTest.DbManager;
using SqlSugarTest.Entities;

namespace ScadaAPI.Services
{
    public class KepWareOpcService :IKepwareOpcService
    {
        public KepWareOpcService()
        {
            //opcClent = new OpcUaSimpleClient();
            OpcServerConfiguration cnf = new OpcServerConfiguration();
            cnf.ClientName = "Test0923";
            cnf.UseConfiguration = true;
            cnf.ServerUrl = "opc.tcp://10.61.140.25:49320";
            cnf.UserName = "OpcUa";
            cnf.Password = "Shris2020";
            cnf.SecerityPolic = 3;

            m_ServerConfig = cnf;

            opcClent = new OpcUaSimpleClient(m_ServerConfig.ClientName, m_ServerConfig.UseConfiguration,
                m_ServerConfig.UserName, m_ServerConfig.Password, m_ServerConfig.SecerityPolic);

           // _dataManager = dataManager;
        }

        private OpcUaSimpleClient opcClent;
        private readonly OpcServerConfiguration m_ServerConfig;
        private readonly RowDataManager _dataManager;

        public async Task Connect()
        {
            await opcClent.Connect(m_ServerConfig.ServerUrl);
        }


        public void DoConnect()
        {
            try
            {
                opcClent.Connect(m_ServerConfig.ServerUrl).Wait();
                Console.WriteLine("connect complete");
            }
            catch (Exception ex)
            {
                Console.WriteLine("connect failed  " + ex.Message);
            }


        }


        List<string> dataAddress = new List<string>();
        List<string> dataTag = new List<string>();
        List<int> dataType = new List<int>();
        public void BrowsNode()
        {
            //找出 用户自定义通道
            ReferenceDescriptionCollection channels = opcClent.FoundUserDefineChannels();

            foreach (var c in channels)
            {
                //Console.WriteLine(c.DisplayName.Text);
                ReferenceDescriptionCollection devices = opcClent.FoundUserDefineNodes(c);

                foreach (var d in devices)
                {
                    //Console.WriteLine(" -" + d.DisplayName.Text);
                    ReferenceDescriptionCollection variables = opcClent.FoundUserDefineVariables(d);
                    foreach (var v in variables)
                    {
                        int type= opcClent.GetVariableDataType(v, Attributes.DataType);
                        dataAddress.Add(v.NodeId.ToString());
                        dataTag.Add(v.DisplayName.Text);
                        dataType.Add(type);


                    }

                }

            }


        }


        public void CreateSubscription()
        {
            opcClent.CreateSubscription(
                "timeMonitor",
                2000,
                2000,
                dataAddress,
                dataTag,
                TimeMonitorHandler
                );
        }

        private void TimeMonitorHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                if (notification != null)
                {
                    for(int i=0;i< dataTag.Count;i++)
                    {
                        if(dataTag[i]== monitoredItem.DisplayName)
                        {
                            RowDatas d = new RowDatas();
                            d.ValueAddress = dataAddress[i];
                            d.ValueType = dataType[i].ToString();
                            d.ValueData = notification.Value.Value.ToString();
                            d.UpdateTime = notification.Value.SourceTimestamp;

                            string data = string.Format("{0}   {1}   {2}   {3}", d.ValueAddress, d.ValueType, d.ValueData, d.UpdateTime.ToLongDateString());
                            Console.WriteLine(data);
                        }
                    }

                    
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Disconnect()
        {
            opcClent.Disconnect();
        }
    }


}